﻿using System;
using System.Collections.Generic;
using WIA;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Shapes;

namespace ScanBook
{
    public class WiaWrapper
    {
        public const string wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}";
        public const string wiaFormatPNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}";
        public const string wiaFormatGIF = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}";
        public const string wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}";
        public const string wiaFormatTIFF = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}";
        //
        //
        private static string DestiantionDirectory { get; set; }
        //
        private static string _ImageFileNamePattern = "img{0:000}.jpg";
        private static string ImageFileNamePattern { get { return _ImageFileNamePattern; } set { _ImageFileNamePattern = value; } }
        //
        public static void SetDestiantionDirectory(string s)
        {
            DestiantionDirectory = s;
        }
        public static void SetImageFileNamePattern(string s)
        {
            ImageFileNamePattern = s;
        }
        //
        //
        public struct ScannerInfo
        {
            public string Name;
            public string DeviceID;
        };
        //
        //
        public static List<ScannerInfo> GetScanners()
        {
            List<ScannerInfo> si = new List<ScannerInfo>();
            try
            {
                WIA.DeviceManager manager = new WIA.DeviceManager();
                //
                foreach (WIA.DeviceInfo info in manager.DeviceInfos)
                {
                    //fff = (string)info.Properties[3].get_Value();//WIA_DIP_VEND_DESC
                    si.Add(new ScannerInfo() { Name = info.Properties[3].get_Value(), DeviceID = info.DeviceID });
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, e.Source);
            }
            return si;
        }
        //
        //
        public static string SelectScanner()
        {
            Device d = null;
            try
            {
                WIA.CommonDialog wiaDialog = new WIA.CommonDialog();
                d = wiaDialog.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, true, false);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, e.Source);
            }
            if (d == null) return "";
            return d.DeviceID;
        }
        //
        public static WIA.Device ConnectScanner(string DeviceID)
        {
            DeviceManager deviceManager = new DeviceManager();
            try
            {
                foreach (DeviceInfo info in deviceManager.DeviceInfos)
                {
                    if (info.DeviceID == DeviceID)
                    {
                        return info.Connect();
                    }
                }
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.Message, "ConnectScanner", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                return null;
            }

            //
            return null;
        }
        //
        public static void SetParameters(WIA.Item wiaItem, bool halfImage = false, int dpi = 300, WiaImageIntent colorMode = WiaImageIntent.GrayscaleIntent)
        {
            wiaItem.Properties.get_Item("6147").set_Value(dpi);//Horizontal Resolution
            wiaItem.Properties.get_Item("6148").set_Value(dpi);//Vertical Resolution (6148)=50
            //
            wiaItem.Properties.get_Item("6146").set_Value(colorMode);//GrayScale
            //
            wiaItem.Properties.get_Item("6149").set_Value(0);//Horizontal Start Position
            wiaItem.Properties.get_Item("6150").set_Value(0);//Vertical Start Position

            //A4 8.27,11.69
            //Letter 8.5 × 11
            if (!halfImage)
            {
                int fullHorizontal = wiaItem.Properties.get_Item("6151").SubTypeMax;
                wiaItem.Properties.get_Item("6151").set_Value(fullHorizontal);//Horizontal Extent
                int fullVertical = wiaItem.Properties.get_Item("6152").SubTypeMax;
                wiaItem.Properties.get_Item("6152").set_Value(fullVertical);//Vertical Extent
            }
            else
            {
                int fullHorizontal = wiaItem.Properties.get_Item("6151").SubTypeMax;
                wiaItem.Properties.get_Item("6151").set_Value(fullHorizontal);//Horizontal Extent
                int fullVertical = wiaItem.Properties.get_Item("6152").SubTypeMax;
                wiaItem.Properties.get_Item("6152").set_Value(fullVertical/2);//Vertical Extent
            }
        }
        //
        public static bool ScanAndSave(WIA.CommonDialog wiaCommonDialog, WIA.Item wiaItem, string fileName, int quality = 90, string wiaFormat = wiaFormatJPEG)
        {
            try
            {
                WIA.ImageFile scannedImage = null;
                scannedImage = wiaCommonDialog.ShowTransfer(wiaItem, wiaFormat, false) as ImageFile;
                //scannedImage = Item1.Transfer(wiaFormatJPEG);

                ImageProcess imgProcess = new ImageProcess();
                object convertFilter = "Convert";
                string convertFilterID = imgProcess.FilterInfos.get_Item(ref convertFilter).FilterID;
                //
                imgProcess.Filters.Add(convertFilterID, 0);
                //FormatID (0)={B96B3CAE-0728-11D3-9D7B-0000F81EF32E}
                //Quality (1)=100
                //Compression (2)=LZW
                imgProcess.Filters[imgProcess.Filters.Count].Properties.get_Item("FormatID").set_Value(wiaFormat);
                imgProcess.Filters[imgProcess.Filters.Count].Properties.get_Item("Quality").set_Value(quality);
                scannedImage = imgProcess.Apply(scannedImage);
                //
                if(File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
                //
                scannedImage.SaveFile(fileName);
                /*
if (imageFile != null)
{
var buffer = imageFile.FileData.get_BinaryData() as byte[];
using (MemoryStream ms = new MemoryStream())
{
ms.Write(buffer, 0, buffer.Length);
pictureBox1.Image = Image.FromStream(ms);
}
}
*/
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.Message, "ScanAndSave", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                return false;
            }
            return true;
        }
        //
        public static int[] GetAvailableDPI(WIA.Item wiaItem)
        {
            return (from hDpi in wiaItem.Properties.get_Item("6147").SubTypeValues.Cast<int>()
                     from vDpi in wiaItem.Properties.get_Item("6148").SubTypeValues.Cast<int>()
                     where hDpi == vDpi
                     orderby hDpi
                     select hDpi).ToArray<int>();
        }
        //
        public static string GetImageFilePathName(int imageNumber)
        {
            return System.IO.Path.Combine(DestiantionDirectory, string.Format(ImageFileNamePattern, imageNumber));
        }
        //
        public static int GetLastPageNumber()
        {
            int n=-1;
            //
            string fp = Regex.Replace(ImageFileNamePattern, "{.*}", "*");
            //
            try
            {
                string[] ff = Directory.GetFiles(DestiantionDirectory, fp);
                //
                foreach (string s in ff)
                {
                    string t = Regex.Replace(System.IO.Path.GetFileName(s), "[^0-9]", "");
                    int m = 0;
                    if (int.TryParse(t, out m))
                    {
                        if (m > n) n = m;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, e.Source);
            }
            return n;
        }
        //
    }//class
}//namespace
